package cn.skyquant.quant4j.service.boot.model.sms;


import cn.skyquant.quant4j.api.dto.ResultDTO;
import cn.skyquant.quant4j.api.enums.RunStatus;
import cn.skyquant.quant4j.api.sms.SmsService;
import cn.skyquant.quant4j.service.boot.model.dict.DictServiceImpl;
import cn.skyquant.quant4j.api.dict.Dictionary;
import cn.skyquant.quant4j.api.enums.SMSType;
import cn.skyquant.quant4j.sdk.util.string.StringUtils;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;


@Service("SmsServiceImpl")
public class SmsServiceImpl implements SmsService{

    @Autowired
    AliDaYuSMSService aliDaYuSMSService;
    @Autowired
    SmsCodeRepository smsCodeRepository;
    final static ResultDTO error = ResultDTO.error("发送短息失败,系统错误");
    final static ResultDTO error1 = ResultDTO.error("发送短息失败,手机号格式不正确");
    final static ResultDTO error2 = ResultDTO.error("短信验证失败");
    final static ResultDTO error3 = ResultDTO.error("5分钟内不能发重复短信");
    final static ResultDTO success = ResultDTO.success("短信验证成功");

    @Autowired
    DictServiceImpl dictServiceImpl;
    String signName ;
    @PostConstruct
    public void init() throws ClientException {
        Dictionary sms = dictServiceImpl.getSmsDict();
        signName = sms.get("signName");
    }

    private static final String templateCode_regcode = "templateCode_regcode";//注册验证码
    private static final String templateCode_identifyingcode = "templateCode_identifyingcode";//登录和修改密码的短信验证码
    private static final String templateCode_balance = "templateCode_balance";//余额提醒
    private static final String templateCode_ea = "templateCode_ea";//ea状态

    //短信注册验证码
    @Override
    public ResultDTO<Void> regCode(String tel) {
        return sendSms(tel,templateCode_regcode,SMSType.REG);
    }


    //短信修改密码验证码
    @Override
    public ResultDTO<Void> loginCode(String tel) {
        return sendSms(tel,templateCode_identifyingcode,SMSType.VERIFY);
    }

    public ResultDTO<Void> checkRegCode(String tel,String code){
        return checkCode(tel,code,SMSType.REG);
    }

    public ResultDTO<Void> checkLoginCode(String tel,String code){
        return checkCode(tel,code,SMSType.VERIFY);
    }

    @Override
    public ResultDTO<Void> balanceNotice(String tel,String name,double balance,double cash) {
        if(tel==null){
            return error1;
        }
        Collection<String> telColl = Sets.newHashSet(tel);
        Dictionary smsDict = dictServiceImpl.getSmsDict();
        String templateCode = smsDict.get(templateCode_balance);
        if(templateCode==null){
            return error;
        }
        Map<String,String> params = new HashMap<>();
        params.put("name", name);
        params.put("balance", String.valueOf(balance));
        params.put("cash", String.valueOf(cash));
        SMS sms = new SMS(telColl,templateCode,signName,params);
        ResultDTO<Void> resultDTO =  aliDaYuSMSService.send(sms);
        return resultDTO;
    }

    @Override
    public ResultDTO<Void> eaStatus(String tel, String accountname, String accountid, String ea, RunStatus status) {
        if(tel==null){
            return error1;
        }
        Collection<String> telColl = Sets.newHashSet(tel);
        Dictionary smsDict = dictServiceImpl.getSmsDict();
        String templateCode = smsDict.get(templateCode_ea);
        if(templateCode==null){
            return error;
        }

        Map<String,String> params = new HashMap<>();
        params.put("accountname", accountname);
        params.put("accountid", accountid);
        params.put("ea", ea);
        params.put("status", status.desc);
        SMS sms = new SMS(telColl,templateCode,signName,params);
        ResultDTO<Void> resultDTO =  aliDaYuSMSService.send(sms);
        return resultDTO;
    }


    public ResultDTO<Void> checkCode(String tel,String code,SMSType type){
        if(tel==null || code==null){
            return error2;
        }
        List<SmsCode> smsCodeList = smsCodeRepository.findByTelTypeExpireTime(tel,type,new Date());
        int num = smsCodeList.stream().filter(x->tel.equals(x.tel) && code.equals(x.code)).collect(Collectors.toList()).size();
        if(num>0){
            return success;
        }else {
            return error2;
        }
    }


    private ResultDTO<Void> sendSms(String tel,String templateCode_str,SMSType type){
        if(tel==null){
            return error1;
        }
        int count = smsCodeRepository.countByTelTypeExpireTime(tel,type,new Date());
        if(count>0){
            return error3;
        }
        Collection<String> telColl = Sets.newHashSet(tel);
        Dictionary smsDict = dictServiceImpl.getSmsDict();
        String templateCode = smsDict.get(templateCode_str);
        if(templateCode==null){
            return error;
        }
        Map<String,String> params = new HashMap<>();
        String code = StringUtils.genNumber(6);
        params.put("code", code);
        SMS sms = new SMS(telColl,templateCode,signName,params);
        ResultDTO<Void> resultDTO =  aliDaYuSMSService.send(sms);

        if(resultDTO.ok){
            SmsCode smsCode = new SmsCode();
            smsCode.tel = tel;
            smsCode.code = code;
            smsCode.type = type;
            smsCode.createdTime = new Date();
            smsCode.expireTime = new Date(smsCode.createdTime.getTime() + 300000);
            smsCodeRepository.save(smsCode);
        }
        return resultDTO;
    }
}
